package com.uu.safeguard.controller;

import com.uu.safeguard.common.Constant;
import com.uu.safeguard.result.Result;
import com.uu.safeguard.result.ResultFactory;
import com.uu.safeguard.service.ChargeLogService;
import com.uu.safeguard.service.MemberRechargeLogService;
import com.uu.safeguard.service.MemberService;
import com.uu.safeguard.utils.CommonUtil;
import com.uu.safeguard.utils.DbUtil;
import com.uu.safeguard.utils.JedisUtil;
import com.uu.safeguard.utils.WsDateUtil;
import net.sf.json.JSONObject;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.*;
import redis.clients.jedis.Jedis;

import javax.annotation.Resource;
import javax.validation.constraints.NotEmpty;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

/**
 * (ChargeLog)表控制层
 *
 * @author makejava
 * @since 2021-07-06 14:08:13
 */
@RestController
@RequestMapping("/chargeLog")
public class ChargeLogController {
    private Logger logger = LoggerFactory.getLogger(ChargeLogController.class);
    /**
     * 服务对象
     */
    @Resource
    private MemberService memberService;

    @Resource
    private MemberRechargeLogService memberRechargeLogService;

    @Resource
    private ChargeLogService chargeLogService;

    /**
     * @Description: 字面意思 设备消费日志
     * @Param: [token, operatorMemberSn, params]
     **/
    @PostMapping("/stationConsumeDayLog")
    public Result stationConsumeDayLog(@RequestHeader("token")String token,
                                       @RequestParam Map<String, String> params){
        String stationSn = params.get("stationSn");
        String searchDate = params.get("searchDate");
        String page = params.get("page");
        String limit = params.get("limit");
        List<LinkedHashMap<String, Object>> stationConsumeDayLogList = null;
        LinkedHashMap<String, Object> stationConsumeDayLogListCount = null;
        if(searchDate.length()==10){
            searchDate+=" 00:00:00";
            stationConsumeDayLogList = chargeLogService
                    .findStationConsumeDayLog(null,stationSn,Integer.parseInt(page),Integer.parseInt(limit), WsDateUtil.getDailyStartTime(WsDateUtil.dateToStamp(searchDate)), WsDateUtil.getDailyEndTime(WsDateUtil.dateToStamp(searchDate)));
            stationConsumeDayLogListCount = chargeLogService
                    .findStationConsumeDayLogCount(null,stationSn,WsDateUtil.getDailyStartTime(WsDateUtil.dateToStamp(searchDate)), WsDateUtil.getDailyEndTime(WsDateUtil.dateToStamp(searchDate)));
        }else if(searchDate.length()==7){
            searchDate+="-01 00:00:00";
            stationConsumeDayLogList = chargeLogService
                    .findStationConsumeDayLog(null,stationSn,Integer.parseInt(page),Integer.parseInt(limit), WsDateUtil.getMonthBegin(WsDateUtil.dateToStamp(searchDate)), WsDateUtil.getMonthEnd(WsDateUtil.dateToStamp(searchDate)));
            stationConsumeDayLogListCount = chargeLogService
                    .findStationConsumeDayLogCount(null,stationSn,WsDateUtil.getMonthBegin(WsDateUtil.dateToStamp(searchDate)), WsDateUtil.getMonthEnd(WsDateUtil.dateToStamp(searchDate)));
        }else if(searchDate.length()==4){
            searchDate+="-01-01 00:00:00";
            stationConsumeDayLogList = chargeLogService
                    .findStationConsumeDayLog(null,stationSn,Integer.parseInt(page),Integer.parseInt(limit), WsDateUtil.getYearBegin(WsDateUtil.dateToStamp(searchDate), Constant.TIME_ZONE), WsDateUtil.getYearEndTime(WsDateUtil.dateToStamp(searchDate), Constant.TIME_ZONE));
            stationConsumeDayLogListCount = chargeLogService
                    .findStationConsumeDayLogCount(null,stationSn,WsDateUtil.getYearBegin(WsDateUtil.dateToStamp(searchDate), Constant.TIME_ZONE), WsDateUtil.getYearEndTime(WsDateUtil.dateToStamp(searchDate), Constant.TIME_ZONE));
        } else{
            return ResultFactory.buildFailResult("请选择正确的查询时间");
        }
        for (int i = 0; i < stationConsumeDayLogList.size(); i++) {
            stationConsumeDayLogList.get(i).put("moneyTotal",Double.parseDouble(CommonUtil.formatMoney(stationConsumeDayLogList.get(i).get("moneyTotal"),2)));
            stationConsumeDayLogList.get(i).put("degreeMoney",Double.parseDouble(CommonUtil.formatMoney(stationConsumeDayLogList.get(i).get("degreeMoney"),2)));
            stationConsumeDayLogList.get(i).put("profit",Double.parseDouble(CommonUtil.formatMoney(stationConsumeDayLogList.get(i).get("profit"),2)));
            stationConsumeDayLogList.get(i).put("memberBalance",Double.parseDouble(CommonUtil.formatMoney(stationConsumeDayLogList.get(i).get("memberBalance"),2)));
        }
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("list",stationConsumeDayLogList);
        jsonObject.put("consumeCount",stationConsumeDayLogListCount.get("consumeCount"));
        jsonObject.put("moneyTotal",Double.parseDouble(CommonUtil.formatMoney(stationConsumeDayLogListCount.get("moneyTotal"),2)));
        //jsonObject.put("degree",Double.parseDouble(CommonUtil.formatMoney(stationConsumeDayLogListCount.get("degree"),2)));
        jsonObject.put("degreeMoney",Double.parseDouble(CommonUtil.formatMoney(stationConsumeDayLogListCount.get("degreeMoney"),2)));
        jsonObject.put("profit",Double.parseDouble(CommonUtil.formatMoney(stationConsumeDayLogListCount.get("profit"),2)));
        return ResultFactory.buildSuccessResult(jsonObject);
    }

    /**
     * @Description: 用户消费次数及消费金额
     * @Param: [token, operatorMemberSn, params]
     **/
    @PostMapping("/memberConsumeMsg")
    public Result memberConsumeMsg(@RequestHeader("token")String token,
                                   @RequestParam Map<String, String> params){
        String memberSn = params.get("memberSn");
        String stationSn = params.get("stationSn");
        //消费次数及消费金额
        LinkedHashMap<String, Object> memberConsumeMsg = memberService.findMemberConsumeMsg(memberSn,null,stationSn);
        memberConsumeMsg.put("consumeMoney",CommonUtil.formatMoney(memberConsumeMsg.get("consumeMoney"),2));
        return ResultFactory.buildSuccessResult(memberConsumeMsg);
    }
    /**
     * @Description: 用户充电列表
     * @Param: [token, operatorMemberSn, params]
     **/
    @PostMapping("/memberChargeList")
    public Result memberChargeList(@RequestHeader("token")String token,
                                   @NotEmpty(message="page 不能为空")String page,
                                   @NotEmpty(message="limit 不能为空")String limit,
                                   @RequestParam Map<String, String> params){
        String memberSn = params.get("memberSn");
        //用户充电列表
        List<LinkedHashMap<String, Object>> memberChargeList = chargeLogService.findMemberChargeList(memberSn,null,Integer.parseInt(page),Integer.parseInt(limit));
        List newMemberChargeList = new ArrayList<>();
        //logger.info(memberChargeList.toString());
        Integer memberChargeListCount = chargeLogService.findMemberChargeListCount(memberSn,null);
        logger.info("列表："+memberChargeList+"--总数："+memberChargeListCount);
        //redis
        Jedis jedis = JedisUtil.getJedis();
        jedis.select(0);
        for (int i = 0; i <memberChargeList.size(); i++) {
            //查询缓存中是否存在.remove(key)
            String redisKey = memberChargeList.get(i).get("socket_sn")+"";
            logger.info("key："+ redisKey);
            if(jedis.exists(redisKey)){
                logger.info("存在的key："+ redisKey);
                Map<String, String> redisParam = jedis.hgetAll(redisKey);
                logger.info("判断："+memberChargeList.get(i).get("id").toString()+"--"+redisParam.get("charge_log_id"));
                if(memberChargeList.get(i).get("id").toString().equals(redisParam.get("charge_log_id"))) {
                    long duration = (System.currentTimeMillis() - Long.valueOf(String.valueOf(memberChargeList.get(i).get("start_time"))));
                    logger.info("实时充电时长(格式化)：" + WsDateUtil.getHMS(duration));
                    memberChargeList.get(i).put("duration", WsDateUtil.getHMS(duration));
                    memberChargeList.get(i).put("charge_log_id", redisParam.get("charge_log_id"));
                    memberChargeList.get(i).put("power_value", redisParam.get("power_value"));
                    memberChargeList.get(i).put("money_total", CommonUtil.formatMoney(redisParam.get("money_total"), 2));
                    memberChargeList.get(i).put("charging_mode", redisParam.get("charging_mode"));
                    newMemberChargeList.add(memberChargeList.get(i));
                    //logger.info("redis:" + redisParam.toString());
                }else{
                    logger.info("charge_log_id 不相同就移除："+ memberChargeList.get(i));
                    logger.info("移除的 key："+ redisKey);
                    //key 不存在就移除
                    //memberChargeList.remove(i);
                    memberChargeListCount--;
                }
            }else{
                logger.info("key 不存在就移除："+ memberChargeList.get(i));
                logger.info("移除的 key："+ redisKey);
                //key 不存在就移除
                //memberChargeList.remove(i);
                memberChargeListCount--;
            }
        }
        //关闭连接
        JedisUtil.close(jedis);
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("count",memberChargeListCount);
        jsonObject.put("list",newMemberChargeList);
        return ResultFactory.buildSuccessResult(jsonObject);
    }

    //充电记录详情
    @PostMapping("detail")
    public Result detail(@RequestHeader("token") String token, Integer id, String sn) {
        DbUtil db = new DbUtil();
        long nowTime = System.currentTimeMillis();
        if( (id  == null || id < 1 ) && (sn == null && StringUtils.isBlank(sn)) ){
            return ResultFactory.buildFailResult("参数有误");
        }

        String whereSql = "";
        List parameter = new ArrayList<Object>();
        if(id != null && id > 0 ){
            parameter.add(id);
            whereSql += " and charge_log.id = ? ";
        }
        if(sn != null && StringUtils.isNotBlank(sn) ){
            parameter.add(sn);
            whereSql += " and charge_log.sn = ? ";
        }

        String sql = "select charge_log.sn as charge_log_sn,charge_log.*,member.avatar,member.mobile,member.nickname,member.nickname_base64,member.balance as now_member_balance,station.name as station_name,project.name as project_name from charge_log left join member on member.sn = charge_log.member_sn left join station on station.sn = charge_log.station_sn left join project on project.sn = charge_log.project_sn where 1 = 1 " + whereSql;

        List list = db.executeQueryBySql(sql, parameter);
        Map charge_log = (Map) list.get(0);

        double degree_price = Double.parseDouble(charge_log.get("degree_price").toString());
        charge_log.put("money_total", CommonUtil.formatMoney(charge_log.get("money_total"),2));
        charge_log.put("member_balance", CommonUtil.formatMoney(charge_log.get("member_balance"),2));
        charge_log.put("degree", CommonUtil.formatMoney(charge_log.get("degree"),2));
        charge_log.put("degree_money", CommonUtil.formatMoney(charge_log.get("degree_money"),2));

        long charging_seconds = 0;
        if((long)charge_log.get("end_time") == 0){ //正在充电
            charging_seconds = (nowTime - (long)charge_log.get("start_time")) / 1000;
            Jedis jedis = JedisUtil.getJedis();
            jedis.select(0);
            String redisKey = charge_log.get("socket_sn").toString();
            if(jedis.exists(redisKey)) {
                Map<String, String> socketInfo = jedis.hgetAll(redisKey);
                charge_log.put("money_total", CommonUtil.formatMoney(socketInfo.get("money_total"),2));
                charge_log.put("degree", CommonUtil.formatMoney(socketInfo.get("degree"),2));
                charge_log.put("degree_money", CommonUtil.formatMoney(Double.parseDouble(socketInfo.get("degree").toString()) * degree_price , 2));
            }
            JedisUtil.close(jedis);

            //正在充电则是实时余额
            charge_log.put("member_balance", CommonUtil.formatMoney(charge_log.get("now_member_balance"),2));
        }else{  //充电完成
            charging_seconds = ((long)charge_log.get("end_time") - (long)charge_log.get("start_time")) / 1000;
        }

        charge_log.put("charging_seconds",charging_seconds);
        int hour = (int)Math.floor(charging_seconds / 3600);
        int minute = (int)Math.floor((charging_seconds - (hour * 3600))  / 60);
        int second = (int)Math.floor((charging_seconds - (hour * 3600) - (minute * 60)) % 60);
        charge_log.put("_charge_hour",hour);
        charge_log.put("_charge_minute",minute);
        charge_log.put("_charge_second",second);

        String start_time = CommonUtil.stampToDate((long) charge_log.get("start_time"));
        charge_log.put("_start_time",start_time);

        String end_time = CommonUtil.stampToDate((long) charge_log.get("end_time"));
        charge_log.put("_end_time",end_time);

        String end_reason = charge_log.get("end_reason").toString();
        charge_log.put("end_reason", Constant.END_REASON_MAP.get(end_reason));


        //利润
        Double profit = Double.parseDouble(charge_log.get("money_total").toString()) - Double.parseDouble(charge_log.get("degree_money").toString());
        charge_log.put("profit",CommonUtil.formatMoney(profit,2));


        String operator_member_sn = charge_log.get("operator_member_sn").toString();
        String station_operator_member_sn = charge_log.get("station_operator_member_sn").toString();
        //查询用户运营信息
        Map operator = db.table("operator").where(new ArrayList(){{
            add(new ArrayList(){{
                add("member_sn");
                add("=");
                add(operator_member_sn);
            }});
        }}).find("name,telephone");
        charge_log.put("operator",operator);
        charge_log.put("station_operator",operator);

        int is_roaming = 0;

        //如果是漫游
        if(!operator_member_sn.equals(station_operator_member_sn)){
            is_roaming = 1;
            //查询设备运营商信息
            Map station_operator = db.table("operator").where(new ArrayList() {{
                add(new ArrayList() {{
                    add("member_sn");
                    add("=");
                    add(station_operator_member_sn);
                }});
            }}).find("name,telephone");

            charge_log.put("station_operator",station_operator);
        }

        charge_log.put("is_roaming",is_roaming);

        //分账记录
        List parameter1 = new ArrayList<Object>();
        parameter1.add(charge_log.get("charge_log_sn"));
        String sql1 = "select member.nickname,member.avatar,member.type as member_type,profit_share_log.share_money from profit_share_log left join member on member.sn = profit_share_log.member_sn where profit_share_log.log_sn = ?";
        List list1 = db.executeQueryBySql(sql1, parameter1);

        if(null == list1 || list1.size() == 0){
            charge_log.put("profit_share",null);
        }else{
            charge_log.put("profit_share",list1);
        }

        return ResultFactory.buildSuccessResult(charge_log);
    }

    /**
     * @Description: 项目用户消费利润列表
     * @Param: [token, operatorMemberSn, params]
     **/
    @PostMapping("/memberConsumeList")
    public Result memberConsumeList(@RequestHeader("token")String token,
                                    @RequestParam Map<String, String> params){
        String memberSn = params.get("memberSn");
        String page = params.get("page");
        String limit = params.get("limit");
        //消费利润列表
        List<LinkedHashMap<String, Object>> memberConsumeList = memberService.findMemberConsumeList(null,null,null,memberSn,Integer.parseInt(page),Integer.parseInt(limit));
        for (int i = 0; i < memberConsumeList.size(); i++) {
            LinkedHashMap<String, Object> map = memberConsumeList.get(i);
            map.put("money_total", CommonUtil.formatMoney(map.get("money_total"),2));
            map.put("degree_money",CommonUtil.formatMoney(map.get("degree_money"),2));
            map.put("profit",CommonUtil.formatMoney(map.get("profit"),2));
            map.put("member_balance",CommonUtil.formatMoney(map.get("member_balance"),2));
        }
        Integer memberConsumeListCount = memberService.findMemberConsumeListCount(null, null, null, memberSn);
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("count",memberConsumeListCount);
        jsonObject.put("list",memberConsumeList);
        return ResultFactory.buildSuccessResult(jsonObject);
    }
    /**
     * @Description: 充电记录列表
     * @Param: [params]
     **/
    @PostMapping("/list")
    public Result list(@RequestParam Map<String, String> params){
        String memberSn = params.get("member_sn");
        if(StringUtils.isEmpty(params.get("member_sn"))){
            return ResultFactory.buildFailResult("请输入用户账号");
        }
        //查询充电记录
        List<LinkedHashMap<String, Object>> chargeLogList = chargeLogService.searchMemberChargeLog(memberSn);
        if(null == chargeLogList){
            return ResultFactory.buildFailResult("查询结果为空");
        }
        for (int i = 0; i < chargeLogList.size(); i++) {
            chargeLogList.get(i).put("start_time",WsDateUtil.stampToDate(chargeLogList.get(i).get("start_time").toString()));
            chargeLogList.get(i).put("end_time",WsDateUtil.stampToDate(chargeLogList.get(i).get("end_time").toString()));
            chargeLogList.get(i).put("time",WsDateUtil.getHMS(Long.parseLong(chargeLogList.get(i).get("time").toString())));
        }
        return ResultFactory.buildSuccessResult(chargeLogList);
    }
}